Recap: 昨天好幾個問題,都是把 event 一個一個印出來才看懂的
到目前為止,我知道的延遲只有一個總數:「第 1 輪 17 秒」
17 秒裡,模型花了多少?工具花了多少?Day 15 說 verify_evidence 一條要求叫一次很浪費,到底浪費在哪?
這些都要靠猜
今天把 Cloud Trace 打開,看一次請求裡面到底發生了什麼
Day 19 讀 AdkApp 原始碼的時候就看到這段
if self._tmpl_attrs.get("enable_tracing"):
os.environ["ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS"] = "true"
else:
os.environ["ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS"] = "false"
網路上的教學大多是這樣開的
app = AdkApp(agent=root_agent, enable_tracing=True)
但這樣會順便把 ADK_CAPTURE_MESSAGE_CONTENT_IN_SPANS 設成 true,也就是把送給模型的內容寫進 trace
我們送給模型的內容,第一行就是整份履歷(Day 16:履歷是填在 instruction 裡的)
新的做法是環境變數,SDK 裡有一張真值表
| enable_tracing | enable_telemetry(env) | tracing_actually_enabled |
| None(default) | true | adk_version >= 1.17 |
enable_tracing 不傳、環境變數設 true,trace 會開,內容不會記
而且 enable_tracing=False 已經被標成要淘汰,傳了會蓋掉環境變數跟 Console 上的開關
所以部署腳本只加一行
"env_vars": {
...
"GOOGLE_CLOUD_AGENT_ENGINE_ENABLE_TELEMETRY": "true",
},
Agent Runtime 的 service agent 本來就有 cloudtrace.traces.patch、telemetry.traces.write 這兩個權限,不用另外開--update 跑了 2 分 34 秒
照 Day 19 的 query_agent.py 打兩輪,再寫一支 scripts/trace_report.py 用 Cloud Trace API 把 trace 拉下來
第一次跑
0 個 trace
以為是 trace 沒送上來,或是要等一陣子
把時間條件拿掉,直接列最近的 trace
count 0 {'nextPageToken': 'GhQIqa2Ljtz...'}
第一頁是空的,但有下一頁
跟著 nextPageToken 翻下去,兩個 trace 都在
只看第一頁的話,會以為整件事沒成功;腳本改成會一直翻到沒有下一頁
trace ce2963e7… 7 個 span
invoke_workflow career_advisor 13313 ms
invoke_agent career_advisor 13053 ms
call_llm 5333 ms
generate_content gemini-2.5-flash 5121 ms
execute_tool verify_evidence 6 ms
call_llm 7628 ms
generate_content gemini-2.5-flash 7524 ms
第 1 輪是 Day 14 那個問題:「幫我看看履歷跟這個職缺的落差」
這次 agent 只叫了一次 verify_evidence
verify_evidence:6 毫秒
第 2 輪查資源
trace 17737c15… 7 個 span
invoke_workflow career_advisor 2715 ms
invoke_agent career_advisor 2551 ms
call_llm 1267 ms
generate_content gemini-2.5-flash 1047 ms
execute_tool lookup_resources 5 ms
call_llm 1216 ms
generate_content gemini-2.5-flash 1115 ms
lookup_resources:5 毫秒
工具幾乎不花時間,時間全在模型
Day 15 寫過「每呼叫一次工具,就要多問模型一次」,那時候只是推論,現在有數字了
工具本身是字串比對、查一份 JSON,幾毫秒就結束;貴的是每叫一次工具,模型就要再被呼叫一次
Day 19 雲端那次一條要求驗證一次,9 次工具呼叫的代價不是 9 × 6 毫秒,而是多了好幾次幾秒鐘的模型呼叫
模型的時間跟著輸出走
每個 generate_content 的 span 上都有 token 數
| 耗時 | 輸入 | 輸出 | 其中 reasoning | |
|---|---|---|---|---|
| 第 1 輪・決定要驗證哪些句子 | 5.1 秒 | 1,916 | 1,019 | 873 |
| 第 1 輪・寫回覆 | 7.5 秒 | 3,135 | 1,490 | 589 |
| 第 2 輪・決定查什麼 | 1.0 秒 | 3,178 | 36 | 30 |
| 第 2 輪・寫回覆 | 1.1 秒 | 3,235 | 39 | — |
第 1 輪的第一次呼叫,產出的其實只是一個工具呼叫(要驗證哪幾句),但花了 5.1 秒,因為它先想了 873 個 token
第 2 輪輸入一樣是 3 千多 token,輸出只有三四十個,就是 1 秒
輸入多不太影響,輸出多、想得多才慢
這個 Day 29 比較成本的時候會用到:要快,該調的是思考的量,不是 prompt 的長度
trace 外面還有 4 秒
query_agent.py 自己量的第 1 輪是 17.3 秒,trace 最外層是 13.3 秒
差的 4 秒不在 trace 裡:請求送到 Agent Runtime、session 讀出來、event 寫回 Sessions,這些都沒有 span
第 2 輪差 0.7 秒
剛部署完的第一個請求,可能還有一些暖機;但到底是哪一段,trace 看不到
trace 只告訴你 agent 裡面發生什麼,不告訴你 agent 外面
打開 trace 之前最擔心的就是這個
Day 17 說「刪除要看位元組」,trace 也一樣,不看就不知道
trace_report.py 會把每個 span 的所有屬性掃一遍,找測試履歷裡一定會出現的字:公司名「沛原科技」、email、電話、一句工作內容
掃過 147 個屬性,沒有履歷內容
不放心,再把屬性印出來看
== execute_tool verify_evidence
gcp.vertex.agent.llm_request = '{}'
gcp.vertex.agent.llm_response = '{}'
gcp.vertex.agent.tool_call_args = '{}'
gcp.vertex.agent.tool_response = '{}'
gen_ai.tool.name = 'verify_evidence'
gen_ai.tool.description = '確認這些引用真的出現在使用者的履歷裡。...'
內容的欄位都是空的 {},留下來的是名字、時間、token 數
有一個例外:gen_ai.tool.description 是工具的 docstring 全文
Day 18 的 guard 把 docstring 當成不能給使用者看的內部說明;在 trace 裡,看得到 trace 的人都看得到
風險不大,但要知道
對照組:舊的 enable_tracing=True
為了確認差別真的是那個參數造成的,在本機用舊參數跑同一個 agent,trace 一樣送到 Cloud Trace
app = AdkApp(agent=build_agent(), enable_tracing=True)
問一句「請引用一句我履歷裡寫到的工作內容,先用工具驗證」
⚠ 履歷內容出現在:
call_llm / gcp.vertex.agent.llm_request: ['沛原科技', 'boyu.chen@example.invalid', '會員中心的登入與權限', '0900-000-001']
call_llm / gcp.vertex.agent.llm_response: ['會員中心的登入與權限']
execute_tool verify_evidence / gcp.vertex.agent.tool_call_args: ['會員中心的登入與權限']
execute_tool verify_evidence / gcp.vertex.agent.tool_response: ['會員中心的登入與權限']
整份履歷,連 email 跟電話,都在 llm_request 裡
工具的參數跟回傳也有履歷原句
同一個 agent、同一個問題,差別只有開 trace 的方式
如果照教學寫了 enable_tracing=True,Day 17 做的刪除就白做了:session 刪掉了,trace 裡還有一份
這個部署設定寫成了測試:make_app() 不能帶 enable_tracing,環境變數要開 telemetry,而且不能有打開內容記錄的那兩個變數
scripts/deploy_agent.py:用環境變數開 telemetry,把 AdkApp 跟設定拆成 make_app()、build_config() 方便測試scripts/trace_report.py:拉 trace、排成樹、掃履歷內容測試從 83 個變成 84 個
對照組那個 trace 裡是虛構的測試履歷,沒有真的個資
版本:google-adk 2.8.0、google-cloud-aiplatform 2.1.0、gemini-2.5-flash
trace 回答了「時間花在哪」,但 trace 外面那 4 秒、雲端出錯時的錯誤訊息,要看 log
問題是:Day 21 才看過,錯誤訊息會把整份履歷附上
明天要做的是,log 裡不能有履歷,出事的時候又要查得到原因